﻿#include "RenderContext.h"
#include <new>

#pragma comment(lib,"libEGL.lib")
#pragma comment(lib,"libGLESv2.lib")

RenderContext::RenderContext(EGLNativeWindowType wnd)
{
    _wnd = wnd;

    _eglContext = new (std::nothrow) EglContext();
    _eglContext->open(wnd);
    _eglContext->use();

    _glesContext = new (std::nothrow) GlesContext();

    _windowsWidth = 0;
    _windowsHeight = 0;

    _imageWidth = 0;
    _imageHeight = 0;

    _renderType = RenderType::fit;
}

RenderContext::~RenderContext()
{
    if (_glesContext)
    {
        delete _glesContext;
        _glesContext = nullptr;
    }

    if (_eglContext)
    {
        delete _eglContext;
        _eglContext = nullptr;
    }
}

void RenderContext::draw()
{
    tagRECT rect;
    GetWindowRect(_wnd, &rect);

    long windowsWidth = rect.right - rect.left;
    long windowsHeight = rect.bottom - rect.top;

    if (_windowsWidth != windowsWidth || _windowsHeight != windowsHeight)
    {
        _windowsWidth = windowsWidth;
        _windowsHeight = windowsHeight;
        updateRenderSize();
    }

    _glesContext->draw(rect.right - rect.left, rect.bottom - rect.top);
    _eglContext->swap();
}

void RenderContext::updateImage(void* buffer[], int inWidth, int inHeight)
{
    if (_imageWidth != inWidth || _imageHeight != inHeight)
    {
        _imageWidth = inWidth;
        _imageHeight = inHeight;
        
        // 窗口宽高置0, 使updateRenderSize()方法在draw()中调用 
        _windowsWidth = 0;
        _windowsHeight = 0;
    }

    glesContext()->updateImage(buffer, inWidth, inHeight);
}

void RenderContext::setRenderType(RenderType renderType)
{
    _renderType = renderType;
}

void RenderContext::updateRenderSize()
{
    float ratio = (float)_imageWidth / (float)_imageHeight;

    float width = _windowsHeight * ratio;
    float height = width / ratio;

    // 是否需要重新计算宽高
    bool recalculation = false;

    // 根据画面填充模式效验数据正确性
    switch (_renderType)
    {
    case RenderType::fit:
        recalculation = width > _windowsWidth;
        break;
    case RenderType::fill:
        recalculation = width < _windowsWidth;
        break;
    default:
        break;
    }

    if (recalculation)
    {
        height = _windowsWidth / ratio;
        width = height * ratio;
    }

    glesContext()->matrix().setScale(width, height);
}
